package com.leyou.item.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exceptions.LyException;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.vo.PageResult;
import com.leyou.item.dto.SkuDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.dto.SpuDetailDTO;
import com.leyou.item.entity.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.omg.CORBA.IRObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.leyou.common.constants.RocketMQConstants.TAGS.ITEM_DOWN_TAGS;
import static com.leyou.common.constants.RocketMQConstants.TAGS.ITEM_UP_TAGS;
import static com.leyou.common.constants.RocketMQConstants.TOPIC.ITEM_TOPIC_NAME;

@Service
public class GoodsService {
//    注入spuService skuService

    @Autowired
    private TbSpuService spuService;
    @Autowired
    private TbSpuDetailService spuDetailService;
    @Autowired
    private TbSkuService skuService;
    @Autowired
    private TbBrandService brandService;
    @Autowired
    private TbCategoryService categoryService;


public PageResult<SpuDTO> findSpuByPage(Integer page, Integer rows, String key, Boolean saleable) {
    QueryWrapper<TbSpu> queryWrapper = new QueryWrapper<>();
    Page<TbSpu> page1 = new Page<>(page,rows);  //构建了分页

//        关键字查询
    if(StringUtils.isNotBlank(key)){
        queryWrapper.lambda().like(TbSpu::getName,key);
    }
    if(saleable!=null){
        queryWrapper.lambda().eq(TbSpu::getSaleable,saleable);
    }
    IPage<TbSpu> spuIPage = spuService.page(page1, queryWrapper);
    long total = spuIPage.getTotal();
    List<TbSpu> tbSpuList = spuIPage.getRecords();
//    判断是否为空
    if(CollectionUtils.isEmpty(tbSpuList)){
        throw  new LyException(ExceptionEnum.GOODS_NOT_FOUND);
    }

    List<SpuDTO> spuDTOList = BeanHelper.copyWithCollection(tbSpuList, SpuDTO.class);
    for (SpuDTO spuDTO : spuDTOList) {
        handlerCategoryNameAndBrandName(spuDTO);
    }
    return new PageResult(total,spuDTOList);
}

    //    提取一个方法专门处理SpuDTO中的商品分类名称、品牌名称
    private SpuDTO handlerCategoryNameAndBrandName(SpuDTO spuDTO){
        //注入品牌的service查询
        TbBrand tbBrand = brandService.getById(spuDTO.getBrandId());
        spuDTO.setBrandName(tbBrand.getName());
        List<Long> categoryIds = spuDTO.getCategoryIds();//三级分类的id //注入分类的service查询
//        直接根据分类id的集合查询分类对象的集合
        Collection<TbCategory> tbCategoryCollection = categoryService.listByIds(categoryIds);
//        从这个集合中获取每个对象的名称 名称和名称之间使用/分隔、
        String categoryNames = tbCategoryCollection.stream(). //变成流
                                map(TbCategory::getName).     //获取每个对象 的名称
                                collect(Collectors.joining("/")); //收集数据，收集的时候吧名称中间用"/"分隔

        spuDTO.setCategoryName(categoryNames);

        return spuDTO;

    }

    @Transactional
    public void saveGoods(SpuDTO spuDTO) {
//     需要保存三张表的数据
//        tb_spu  -- > spuDTO转TbSpu
        TbSpu tbSpu = BeanHelper.copyProperties(spuDTO, TbSpu.class);
        spuService.save(tbSpu);
        Long spuId = tbSpu.getId();
//        tb_spu_detail --->  spuDTO.getSpuDetail()转TbSpuDetail
        TbSpuDetail tbSpuDetail = BeanHelper.copyProperties(spuDTO.getSpuDetail(), TbSpuDetail.class);
//        需要构建TBSPUDetail和 tbSpu的一对一关系
        tbSpuDetail.setSpuId(spuId);
        spuDetailService.save(tbSpuDetail);
//        tb_sku --->  spuDTO.getSkus() 转TbSku
        List<TbSku> tbSkus = BeanHelper.copyWithCollection(spuDTO.getSkus(), TbSku.class);
        for (TbSku sku : tbSkus) {
            sku.setSpuId(spuId);
        }
        skuService.saveBatch(tbSkus); //批量保存 执行的是一个SQL语句

    }

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    public void updateSaleable(Long id, Boolean saleable) {
//     update tb_spu set saleable=? where id=?
        UpdateWrapper<TbSpu> updateWrapper = new UpdateWrapper();
        updateWrapper.lambda().eq(TbSpu::getId,id); // where id=?
        updateWrapper.lambda().set(TbSpu::getSaleable,saleable) ; //set saleable=?
        boolean isUpdate = spuService.update(updateWrapper);
        if(!isUpdate){ //如果失败
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
//        还需要修改此spu下的sku数据enable
//        update tb_sku set enable=? where spu_id=?
        UpdateWrapper<TbSku> updateWrapper1 = new UpdateWrapper();
        updateWrapper1.lambda().eq(TbSku::getSpuId,id); // where spu_id=?
        updateWrapper1.lambda().set(TbSku::getEnable,saleable) ; //set saleable=?
        boolean isUpdate1 = skuService.update(updateWrapper1);
        if(!isUpdate1){ //如果失败
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
//        saleable:true false  上架  下架
//      向MQ中发送消息 ITEM_UP_TAGS  ITEM_DOWN_TAGS
        String tag = saleable?ITEM_UP_TAGS:ITEM_DOWN_TAGS;
        rocketMQTemplate.convertAndSend(ITEM_TOPIC_NAME+":"+tag,id);

        System.out.println("上下架成功，MQ消息已发送："+tag);
    }

    public SpuDetailDTO findSpuDetailBySpuId(Long id) {
        TbSpuDetail tbSpuDetail = spuDetailService.getById(id); //getById==getByPrimaryKey根据主键查询
        if(tbSpuDetail==null){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyProperties(tbSpuDetail,SpuDetailDTO.class);
    }

    public List<SkuDTO> findSkuListBySpuId(Long id) {
//     select * from tb_sku where spu_id=?
        QueryWrapper<TbSku> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TbSku::getSpuId,id);
        List<TbSku> tbSkuList = skuService.list(queryWrapper);
        if(CollectionUtils.isEmpty(tbSkuList)){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
       return BeanHelper.copyWithCollection(tbSkuList,SkuDTO.class);
    }

    @Transactional
    public void updateGoods(SpuDTO spuDTO) {
//     需要保存三张表的数据
//        tb_spu  -- > spuDTO转TbSpu
        TbSpu tbSpu = BeanHelper.copyProperties(spuDTO, TbSpu.class);
        spuService.updateById(tbSpu);
        Long spuId = tbSpu.getId();
//        tb_spu_detail --->  spuDTO.getSpuDetail()转TbSpuDetail
        TbSpuDetail tbSpuDetail = BeanHelper.copyProperties(spuDTO.getSpuDetail(), TbSpuDetail.class);
        spuDetailService.updateById(tbSpuDetail);
//        tb_sku --->  spuDTO.getSkus() 转TbSku
//        先删除后新增
//        delete from tb_sku where spu_id=?

        QueryWrapper<TbSku> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(TbSku::getSpuId,spuId); // where spu_id=?
        skuService.remove(queryWrapper); //相当于执行了delete操作

        List<TbSku> tbSkus = BeanHelper.copyWithCollection(spuDTO.getSkus(), TbSku.class);
        for (TbSku sku : tbSkus) {
            sku.setSpuId(spuId);
        }
        skuService.saveBatch(tbSkus); //批量保存 执行的是一个SQL语句
    }

    public SpuDTO findSpuBySpuId(Long id) {
        TbSpu tbSpu = spuService.getById(id);
        return BeanHelper.copyProperties(tbSpu,SpuDTO.class);
    }

    public List<SkuDTO> findSkuListBySkuIds(List<Long> ids) {
        Collection<TbSku> tbSkus = skuService.listByIds(ids);
        return  tbSkus.stream().map(tbsku->{
            return BeanHelper.copyProperties(tbsku,SkuDTO.class);
        }).collect(Collectors.toList());
    }

    public void stockMinus(Map<Long, Integer> skuIdAndNumMap) {
        skuService.stockMinus(skuIdAndNumMap);

    }

    public void stockPlus(Map<Long, Integer> skuIdAndNumMap) {
        skuService.stockPlus(skuIdAndNumMap);
    }

    public List<SpuDTO> findSpuByPage(Long brandId, Long cid) {
        QueryWrapper<TbSpu> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(TbSpu::getBrandId,brandId).eq(TbSpu::getCid3,cid);
        List<TbSpu> tbSpuList = spuService.list(queryWrapper);
        if(CollectionUtils.isEmpty(tbSpuList)){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(tbSpuList,SpuDTO.class);


    }
}
